package org.levi.demo.mybatis.plugin.plugins;

import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.parser.CCJSqlParserManager;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.select.FromItem;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import org.levi.demo.mybatis.plugin.annotation.DataPermission;
import org.levi.demo.mybatis.plugin.util.AnnotationUtil;
import org.levi.demo.mybatis.plugin.util.StringUtil;

import java.io.StringReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DataAuthSqlBuilder {

    private String originSql;
    private DataPermission[] permissions;
    private Map<String, String> resourceMap;

    public DataAuthSqlBuilder(String originSql, DataPermission[] permissions) {
        this.originSql = originSql;
        this.permissions = permissions;
        initPermission();
    }

    private void initPermission() {
        resourceMap = new HashMap<>();
        resourceMap.put("1", "country = 1");
        resourceMap.put("2", "country = 2");
        resourceMap.put("11", "order_type = 1");
        resourceMap.put("22", "order_type = 2");
    }

    public String getPermissionSql() throws JSQLParserException {
        CCJSqlParserManager parserManager = new CCJSqlParserManager();
        Select select = (Select) parserManager.parse(new StringReader(originSql));
        PlainSelect plain = (PlainSelect) select.getSelectBody();
        for (DataPermission permission : permissions) {
            String resourceId = (String) AnnotationUtil.getAnnotationValue(permission, "resourceId");
            String tableName = (String) AnnotationUtil.getAnnotationValue(permission, "tableName");
            String tableAlias = (String) AnnotationUtil.getAnnotationValue(permission, "tableAlias");
            if (StringUtil.isEmpty(tableName) && StringUtil.isEmpty(tableAlias)) {
                throw new RuntimeException("tableName and tableAlias both empty!");
            }
            String prefix = StringUtil.isEmpty(tableAlias) ? tableName : tableAlias;
            String authSql = resourceMap.get(resourceId);
            if (plain.getWhere() == null) {
                plain.setWhere(CCJSqlParserUtil.parseCondExpression(prefix + "."+authSql));
            } else {
                plain.setWhere(new AndExpression(plain.getWhere(), CCJSqlParserUtil.parseCondExpression(prefix + "."+authSql)));
            }
        }
        String finalSql = select.toString();
        return finalSql;
    }

    /*public String getPermissionSql() throws JSQLParserException {

        String[] sqlSpecies = originSql.toUpperCase().split("WHERE");
        CCJSqlParserManager parserManager = new CCJSqlParserManager();
        Select select = (Select) parserManager.parse(new StringReader(originSql));
        PlainSelect plain = (PlainSelect) select.getSelectBody();
        if (plain.getWhere() == null) {
            plain.setWhere(CCJSqlParserUtil.parseCondExpression("1=1"));
        } else {
            plain.setWhere(new AndExpression(plain.getWhere(), CCJSqlParserUtil.parseCondExpression("t.order_type = 1")));
        }
        String sql = sqlSpecies[0];
        int index = 0;
        for (DataPermission permission : permissions) {
            String resourceId = (String) AnnotationUtil.getAnnotationValue(permission, "resourceId");
            String tableName = (String) AnnotationUtil.getAnnotationValue(permission, "tableName");
            String tableAlias = (String) AnnotationUtil.getAnnotationValue(permission, "tableAlias");
            if (StringUtil.isEmpty(tableName) && StringUtil.isEmpty(tableAlias)) {
                throw new RuntimeException("tableName and tableAlias both empty!");
            }
            String prefix = StringUtil.isEmpty(tableAlias) ? tableName : tableAlias;
            String authSql = resourceMap.get(resourceId);
            StringBuilder subAuth = null;
            if (index == 0) {
                subAuth = new StringBuilder(" WHERE (");
            } else {
                subAuth = new StringBuilder(" AND ( ");
            }

            if (authSql == null || " ".equals(authSql)) {
                subAuth.append("1 != 1)");
            } else {
                subAuth.append(prefix).append(".").append(authSql).append(" )");
            }
            sql += subAuth.toString();
            ++index;
        }
        if (sqlSpecies.length > 1) {
            sql += " AND ";
            for (int i = 1; i < sqlSpecies.length; i++) {
                sql += sqlSpecies[i];
            }
        }
        return sql;
    }*/



}
